using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace cosoware.MSBuildTasks.Subversion
{
    /// <summary>
    /// Gets information about subverion working copy or reporitory.
    /// </summary>
    public class SvnInfo : SvnXmlTask
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SvnInfo"/> class.
        /// </summary>
        public SvnInfo()
        {
        }

        /// <summary>
        /// Gets the info command.
        /// </summary>
        /// <value>The command.</value>
        protected override string Command
        {
            get { return "info"; }
        }

        /// <summary>
        /// Gets or sets the target.
        /// Targer may be either a working-copy path or URL.
        /// Defauit value is ".".
        /// </summary>
        /// <value>The target.</value>
        public ITaskItem Target
        {
            get { return GetInputTaskItem("Target"); }
            set { InitializeInputTaskItem("Target", value); }
        }

        /// <summary>
        /// Gets the kind of the target.
        /// </summary>
        /// <value>The kind of the target.</value>
        [Output]
        public ITaskItem NodeKind
        {
            get { return GetOutputTaskItem("NodeKind"); }
        }

        /// <summary>
        /// Gets the target path.
        /// </summary>
        /// <value>The target path.</value>
        [Output]
        public ITaskItem Path
        {
            get { return GetOutputTaskItem("Path"); }
        }

        /// <summary>
        /// Gets the target URL.
        /// </summary>
        /// <value>The target URL.</value>
        [Output]
        public ITaskItem Url
        {
            get { return GetOutputTaskItem("Url"); }
        }

        /// <summary>
        /// Gets the target revision.
        /// </summary>
        /// <value>The target revision.</value>
        [Output]
        public ITaskItem Revision
        {
            get { return GetOutputTaskItem("Revision"); }
        }

        /// <summary>
        /// Gets the repository root.
        /// </summary>
        /// <value>The repository root.</value>
        [Output]
        public ITaskItem RepositoryRoot
        {
            get { return GetOutputTaskItem("RepositoryRoot"); }
        }

        /// <summary>
        /// Gets the repository UUID.
        /// </summary>
        /// <value>The repository UUID.</value>
        [Output]
        public ITaskItem RepositoryUUID
        {
            get { return GetOutputTaskItem("RepositoryUUID"); }
        }

        /// <summary>
        /// Gets the last changed author.
        /// </summary>
        /// <value>The last changed author.</value>
        [Output]
        public ITaskItem LastChangedAuthor
        {
            get { return GetOutputTaskItem("LastChangedAuthor"); }
        }

        /// <summary>
        /// Gets the last changed revision.
        /// </summary>
        /// <value>The last changed revision.</value>
        [Output]
        public ITaskItem LastChangedRevision
        {
            get { return GetOutputTaskItem("LastChangedRevision"); }
        }

        /// <summary>
        /// Gets the last changed date.
        /// </summary>
        /// <value>The last changed date.</value>
        [Output]
        public ITaskItem LastChangedDate
        {
            get { return GetOutputTaskItem("LastChangedDate"); }
        }

        [Output]
        public ITaskItem LockToken
        {
            get { return GetOutputTaskItem("LockToken"); }
        }

        /// <summary>
        /// Gets the lock owner.
        /// </summary>
        /// <value>The lock owner.</value>
        [Output]
        public ITaskItem LockOwner
        {
            get { return GetOutputTaskItem("LockOwner"); }
        }

        /// <summary>
        /// Gets the lock created.
        /// </summary>
        /// <value>The lock created.</value>
        [Output]
        public ITaskItem LockCreated
        {
            get { return GetOutputTaskItem("LockCreated"); }
        }

        /// <summary>
        /// Gets the lock expires.
        /// </summary>
        /// <value>The lock expires.</value>
        [Output]
        public ITaskItem LockExpires
        {
            get { return GetOutputTaskItem("LockExpires"); }
        }

        /// <summary>
        /// Builds the parameters command line.
        /// </summary>
        protected override void BuildCommandLine()
        {
            AppendSwitch(Target);
            base.BuildCommandLine();
        }

        /// <summary>
        /// Runs after execute.
        /// </summary>
        /// <returns></returns>
        protected override bool AfterExecute()
        {
            if (!base.AfterExecute())
                return false;
            // Entry properties
            try
            {
                CreateOutputFromXmlNode("NodeKind", @"/info/entry/@kind", true);
                CreateOutputFromXmlNode("Path", @"/info/entry/@path", true);
                CreateOutputFromXmlNode("Name", @"/info/entry/url", true);
                CreateOutputFromXmlNode("Revision", @"/info/entry/@revision", true);
                // Repository information
                CreateOutputFromXmlNode("RepositoryRoot", @"/info/entry/repository/root", true);
                CreateOutputFromXmlNode("RepositoryUUID", @"/info/entry/repository/uuid", true);
                // Last changed information
                CreateOutputFromXmlNode("LastChangedRevision", @"/info/entry/commit/@revision");
                CreateOutputFromXmlNode("LastChangedDate", @"/info/entry/commit/date");
                CreateOutputFromXmlNode("LastChangedAuthor", @"/info/entry/commit/author");
                // Working copy information

                // Lock information
                /*
                LockToken
                LockOwner
                LockCreated
                LockExpires
                 */
            }
            catch (SvnTaskException e)
            {
                Log.LogErrorFromException(e);
                return false;
            }
            return true;
        }
    }
}
